
#ifndef __LOADER_H
#define __LOADER_H

#include "includes.h"

struct function_info
{
  int id;
  char *name;
  void *bytecode_address;
  void *compiled_address;
  struct function_info *next;
};

struct function_info *
function_lookup_by_id(int id);

void *
load_bytecode(char *filename); 

void
load_main_lib();


//Byte code structures

typedef struct 
{
  unsigned char op : 8  __attribute__((packed));
  unsigned int arg : 32 __attribute__((packed));
} op1arg32;

typedef struct
{
  unsigned char op : 8 __attribute__((packed));
  unsigned int arg : 8 __attribute__((packed));
} op1arg8;

typedef struct
{
  unsigned char op : 8 __attribute__((packed));
  unsigned char arg[]  __attribute__((packed));
} opstrarg;

typedef struct 
{
  unsigned char op : 8     __attribute__((packed));
  unsigned int numargs : 8 __attribute__((packed));
  char name[]              __attribute__((packed));
} named_fcall;

typedef struct 
{
  unsigned char op : 8       __attribute__((packed));
  unsigned int ncallargs : 8 __attribute__((packed));
  unsigned int numargs : 8   __attribute__((packed));
  char name[]                __attribute__((packed));
} named_tcall;

typedef struct
{
  unsigned char op : 8 __attribute__((packed));
  char name[];
} named_spawn;



//In-memory structures
/** In memory structures.  These structures are the byte codes as they
 * are stored in memory during execution. 
 */
typedef union
{
  char op __attribute__((packed));
  
  struct 
  {
    unsigned char op : 8  __attribute__((packed));
    unsigned int arg : 32 __attribute__((packed));
  } op1arg32;

  struct 
  {
    unsigned char op : 8 __attribute__((packed));
    unsigned int arg : 8 __attribute__((packed));
  } op1arg8;

  struct
  {
    unsigned char op : 8 __attribute__((packed));
    YJK_BIGINT bigint    __attribute__((packed));
  } opbigint;

  struct
  {
    unsigned char op : 8 __attribute__((packed));
    unsigned char arg[]  __attribute__((packed));
  } opstrarg;
  
  struct 
  {
    unsigned char op : 8     __attribute__((packed));
    unsigned int numargs : 8 __attribute__((packed));
    unsigned int addr        __attribute__((packed));
  } fcall;
  
  struct 
  {
    unsigned char op : 8     __attribute__((packed));
    unsigned int numargs : 8 __attribute__((packed));
    void (*addr)(void)       __attribute__((packed));
  } cfcall;

  struct 
  {
    unsigned char op : 8       __attribute__((packed));
    unsigned int ncallargs : 8 __attribute__((packed));
    unsigned int numargs : 8   __attribute__((packed));
    unsigned int addr          __attribute__((packed));
  } tcall;

  struct
  {
    unsigned char op : 8       __attribute__((packed));
    unsigned int func_id : 32  __attribute__((packed));
  } spawn;

  struct
  {
    unsigned char op : 8       __attribute__((packed));
    double n                   __attribute__((packed));
  } opdblarg;

} yjk_bcmem;


#endif
